use honeybee::prelude::*;
use honeybee::Result;

#[derive(Default)]
pub struct RoomManager {}

impl Service for RoomManager {}

#[async_trait::async_trait]
impl Actor for RoomManager {
    fn name(&self) -> &str {
        "RoomManager"
    }

    async fn started(&mut self, ctx: &mut Context<Self>) -> Result<()> {
        info!("room manager actor:{} started", ctx.actor_id());
        //let router = ctx.get_router().await?;
        /*router.register::<proto::ReqHelloWorld>();
        router.register::<proto::UserOnlineNotifyRoom>();

        router.register_rpc::<proto::Add>();
        router.register_rpc::<proto::GetValue>();
        router.register_rpc::<proto::GetScores>();
        */
        Ok(())
    }

    async fn stopped(&mut self, _ctx: &mut Context<Self>) {
        info!("room manager actor stoped");
    }
}

pub struct AddResult(pub u32);
#[message(result = "AddResult")]
pub struct Add(pub u32, pub u32);
#[async_trait::async_trait]
impl Handler<Add> for RoomManager {
    async fn handle(&mut self, _ctx: &mut Context<Self>, msg: Add) -> Result<AddResult> {
        Ok(AddResult(msg.0 + msg.1))
    }
}

/*
#[async_trait::async_trait]
impl Handler<NetMsg<proto::ReqHelloWorld>> for RoomManager {
    async fn handle(
        &mut self,
        _ctx: &mut Context<Self>,
        msg: NetMsg<proto::ReqHelloWorld>,
    ) -> Result<()> {
        let (source_addr, msg) = (msg.source, msg.msg);
        debug!(
            "room actor process message:{:?} source_addr:{}",
            msg,
            source_addr.actor_id()
        );

        source_addr.send_remote(proto::RspHelloWorld { a: msg.a, b: msg.b });

        Ok(())
    }
}

#[async_trait::async_trait]
impl Handler<NetMsg<proto::UserOnlineNotifyRoom>> for RoomManager {
    async fn handle(
        &mut self,
        _ctx: &mut Context<Self>,
        msg: NetMsg<proto::UserOnlineNotifyRoom>,
    ) -> Result<()> {
        let (source_addr, msg) = (msg.source, msg.msg);
        debug!(
            "room actor process message:{:?} source_addr:{}",
            msg,
            source_addr.actor_id()
        );

        source_addr.send_to_app_user(1, proto::RoomChangeAppUserData { a: 1 });
        let mut rsp = room::RspCreateRoomState::default();
        rsp.successed = true;
        source_addr.send_to_user(1, rsp);

        Ok(())
    }
}

#[async_trait::async_trait]
impl Handler<proto::Add> for RoomManager {
    async fn handle(&mut self, _ctx: &mut Context<Self>, msg: proto::Add) -> Result<u32> {
        Ok(msg.0 + msg.1)
    }
}

#[async_trait::async_trait]
impl Handler<proto::GetValue> for RoomManager {
    async fn handle(
        &mut self,
        _ctx: &mut Context<Self>,
        _msg: proto::GetValue,
    ) -> Result<Vec<String>> {
        Ok(vec!["hello.world".to_string(), "xxxx".to_string()])
    }
}

#[async_trait::async_trait]
impl Handler<proto::GetScores> for RoomManager {
    async fn handle(
        &mut self,
        _ctx: &mut Context<Self>,
        _msg: proto::GetScores,
    ) -> Result<proto::Scores> {
        Ok(proto::Scores {
            scores: vec![1, 15, 60, 100],
        })
    }
}
*/
